/**
 * Token管理器 - 处理JWT token的自动刷新
 */

import { useAccessStore } from '@vben/stores';

import { isJwtTokenExpired } from './jwt-utils';

export class TokenManager {
  private refreshPromise: null | Promise<string> = null;
  private refreshTimer: NodeJS.Timeout | null = null;
  /**
   * 检查并主动刷新即将过期的token
   */
  public async checkAndRefreshToken(): Promise<null | string> {
    const accessStore = useAccessStore();

    if (!accessStore.accessToken || !accessStore.refreshToken) {
      return null;
    }

    if (isJwtTokenExpired(accessStore.accessToken, 5)) {
      try {
        return await this.refreshToken();
      } catch (error) {
        console.error('主动刷新token失败:', error);
        return null;
      }
    }

    return accessStore.accessToken;
  }

  /**
   * 刷新token（如果正在刷新则返回已有的Promise）
   */
  public async refreshToken(): Promise<string> {
    if (this.refreshPromise) {
      return this.refreshPromise;
    }

    this.refreshPromise = this.doRefreshToken();

    try {
      const newToken = await this.refreshPromise;
      return newToken;
    } finally {
      this.refreshPromise = null;
    }
  }

  /**
   * 启动token自动刷新定时器
   */
  public startAutoRefresh(): void {
    this.scheduleNextRefresh();
  }

  /**
   * 停止token自动刷新定时器
   */
  public stopAutoRefresh(): void {
    if (this.refreshTimer) {
      clearTimeout(this.refreshTimer);
      this.refreshTimer = null;
    }
  }

  /**
   * 执行实际的token刷新
   */
  private async doRefreshToken(): Promise<string> {
    const accessStore = useAccessStore();

    if (!accessStore.refreshToken) {
      throw new Error('没有可用的刷新令牌');
    }

    try {
      const { refreshTokenApi } = await import('./auth');
      const refreshResult = await refreshTokenApi();
      const newToken = refreshResult.data;

      // 更新存储的token
      accessStore.setAccessToken(newToken);

      console.log('Token刷新成功');
      return newToken;
    } catch (error) {
      console.error('刷新token失败:', error);
      // 刷新失败，清除所有token
      accessStore.setAccessToken(null);
      accessStore.setRefreshToken(null);
      throw error;
    }
  }

  /**
   * 计划下次刷新时间
   */
  private scheduleNextRefresh(): void {
    const accessStore = useAccessStore();

    if (!accessStore.accessToken || !accessStore.refreshToken) {
      return;
    }

    try {
      import('./jwt-utils').then(({ getJwtTokenRemainingTime }) => {
        const remainingTime = getJwtTokenRemainingTime(accessStore.accessToken);

        if (remainingTime <= 0) {
          // Token已过期，立即刷新
          this.refreshToken();
          return;
        }

        // 在token过期前5分钟刷新
        const refreshTime = Math.max(remainingTime - 5 * 60 * 1000, 30 * 1000); // 最少30秒后刷新

        this.refreshTimer = setTimeout(() => {
          this.refreshToken()
            .then(() => {
              // 刷新成功后，重新计划下次刷新
              this.scheduleNextRefresh();
            })
            .catch((error) => {
              console.error('定时刷新token失败:', error);
              // 刷新失败，可能需要重新登录
            });
        }, refreshTime);

        console.log(`Token将在 ${Math.round(refreshTime / 1000)} 秒后自动刷新`);
      });
    } catch (error) {
      console.error('计划token刷新失败:', error);
    }
  }
}

// 导出单例实例
export const tokenManager = new TokenManager();
